package com.github.lee.mvvm.core.ui

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.annotation.IntRange
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import com.github.lee.mvvm.core.databinding.LayoutBaseHoverBinding
import com.github.lee.mvvm.core.databinding.LayoutBaseLinearBinding
import com.github.lee.mvvm.core.util.viewGone
import com.github.lee.mvvm.core.vm.BaseViewModel
import qiu.niorgai.StatusBarCompat

abstract class BaseFragment<VB : ViewDataBinding, VM : BaseViewModel> : Fragment() {
    protected val mContext by lazy { requireActivity() }
    protected var isToolbarHover = false

    protected var loadingView: View? = null
    protected var pageVB: VB? = null
    protected var emptyView: View? = null
    protected var errorView: View? = null

    protected lateinit var pageVM: VM

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        onInitData(savedInstanceState)
        pageVM = onCreateViewModel()
        lifecycle.addObserver(pageVM)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val rootVB = if (isToolbarHover) {
            LayoutBaseHoverBinding.inflate(layoutInflater)
                .also {
                    it.lifecycleOwner = this
                    showLayout(it.flBaseToolbarContainer, it.flBaseContentContainer)
                    val p = it.flBaseToolbarContainer.layoutParams as RelativeLayout.LayoutParams
                    p.topMargin = getStatusBarHeight()
                    it.flBaseToolbarContainer.requestLayout()

                }
        } else {
            LayoutBaseLinearBinding.inflate(layoutInflater)
                .also {
                    it.unbind()
                    it.lifecycleOwner = this
                    showLayout(it.flBaseToolbarContainer, it.flBaseContentContainer)

                }
        }
        rootVB.lifecycleOwner = this

        return rootVB.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        onObserveData()
        if (null != loadingView) {
            pageVM.uiObserve.postValue(BaseViewModel.UiModel.loading())
        } else {
            if (null != pageVB) {
                pageVM.uiObserve.postValue(BaseViewModel.UiModel.success())
            }
        }
        onSetViewListener()
        onSetViewData()
    }

    //===Desc:=========================================================
    private fun showLayout(toolbarContainer: FrameLayout, contentContainer: FrameLayout) {
        onCreateToolbar().apply {
            if (null != this) {
                toolbarContainer.removeAllViews()
                val a = activity
                if (a is AppCompatActivity) {
                    a.setSupportActionBar(this)
                }
                toolbarContainer.addView(this)
                viewGone(toolbarContainer, false)
            } else {
                viewGone(toolbarContainer, true)
            }
        }

        onCreateLoading().apply {
            loadingView = this
            if (null != this) {
                contentContainer.addView(this)
                viewGone(this, true)
            }
        }

        pageVB?.apply {
            this.lifecycleOwner = viewLifecycleOwner
            contentContainer.addView(this.root)
            viewGone(this.root, true)
        }

        onCreateSuccess().apply {
            pageVB = this
            if (null != this) {
                this.lifecycleOwner = viewLifecycleOwner
                contentContainer.addView(this.root)
                viewGone(this.root, true)
            }
        }

        onCreateEmpty().apply {
            emptyView = this
            if (null != this) {
                contentContainer.addView(this)
                viewGone(this, true)
            }
        }

        onCreateError().apply {
            errorView = this
            if (null != this) {
                contentContainer.addView(this)
                viewGone(this, true)
            }
        }
    }

    //===Desc:=========================================================


    protected open fun onInitData(savedInstanceState: Bundle?) {}

    protected open fun onObserveData() {
        pageVM.apply {
            throwableLiveData.observe(viewLifecycleOwner) {
                Log.e("TTTT", "error", it)
            }
            uiObserve.observe(viewLifecycleOwner) {
                if (null == it) {
                    return@observe
                }
                when (it.pageEvent) {
                    BaseViewModel.PageEvent.LOADING -> {
                        if (null != loadingView) {
                            viewGone(loadingView, false)
                            viewGone(pageVB?.root, true)
                            viewGone(emptyView, true)
                            viewGone(errorView, true)
                        }
                    }
                    BaseViewModel.PageEvent.SUCCESS -> {
                        if (null != pageVB) {
                            viewGone(loadingView, true)
                            viewGone(pageVB?.root, false)
                            viewGone(emptyView, true)
                            viewGone(errorView, true)
                        }
                    }
                    BaseViewModel.PageEvent.EMPTY -> {
                        if (null != emptyView) {
                            viewGone(loadingView, true)
                            viewGone(pageVB?.root, true)
                            viewGone(emptyView, false)
                            viewGone(errorView, true)
                        }
                        onUiStateEmptyOrError(true, it.icon, it.msg)
                    }
                    BaseViewModel.PageEvent.ERROR -> {
                        if (null != errorView) {
                            viewGone(loadingView, true)
                            viewGone(pageVB?.root, true)
                            viewGone(emptyView, true)
                            viewGone(errorView, false)
                        }
                        onUiStateEmptyOrError(false, it.icon, it.msg)
                    }
                    BaseViewModel.PageEvent.WAIT -> {
                        //显示加载中
                    }
                    BaseViewModel.PageEvent.TOAST -> {
                        if (it.msg.isNotEmpty()) {
                            Toast.makeText(mContext, it.msg, Toast.LENGTH_SHORT).show()
                        }
                    }
                }
            }
        }
    }

    protected open fun onSetViewListener() {}
    protected open fun onSetViewData() {}

    //===Desc:=========================================================

    protected abstract fun onCreateViewModel(): VM

    protected open fun onCreateToolbar(): Toolbar? = null
    protected open fun onCreateLoading(): View? = null
    protected open fun onCreateSuccess(): VB? = null
    protected open fun onCreateEmpty(): View? = null
    protected open fun onCreateError(): View? = null

    //===Desc:=========================================================

    protected open fun onUiStateEmptyOrError(
        isEmpty: Boolean,
        @DrawableRes icon: Int = -1,
        msg: String = ""
    ) {
    }


    //===Desc:状态栏相关=========================================================


    protected fun setStatusBarColor(
        @ColorInt color: Int,
        @IntRange(from = 0, to = 255) alpha: Int? = null
    ) {
        val a = activity
        if (a is AppCompatActivity) {
            if (null == alpha) {
                StatusBarCompat.setStatusBarColor(a, color)
            } else {
                StatusBarCompat.setStatusBarColor(a, color, alpha)
            }
        }
    }

    protected fun translucentStatusBar(hideStatusBarBackground: Boolean = false) {
        val a = activity
        if (a is AppCompatActivity) {
            StatusBarCompat.translucentStatusBar(a, hideStatusBarBackground)
        }

    }

    protected fun changeStatusBarTextColor(isBlack: Boolean) {
        val a = activity
        if (a is AppCompatActivity) {
            if (isBlack) {
                StatusBarCompat.changeToLightStatusBar(a)
            } else {
                StatusBarCompat.cancelLightStatusBar(a)
            }
        }
    }


    protected fun getStatusBarHeight(): Int {
        val resId = resources.getIdentifier("status_bar_height", "dimen", "android")
        return if (resId > 0) {
            resources.getDimensionPixelOffset(resId)
        } else {
            0
        }
    }
}